﻿namespace ScrumLite.WebUx.Controllers
{
    using System;
    using System.Web.Mvc;
    using System.Collections.ObjectModel;
    using ScrumLite.Services;
    using ScrumLite.WebUx.Models;
    using ScrumLite.Services.Contracts;
    using System.Configuration;
    using System.Collections.Generic;
    using System.Linq;
    using ScrumLite.Gateways;
    using System.Globalization;
    using System.Security.Permissions;

    public class ProjectsController : ContextBaseController
    {
        IRolesService roles;
        IAbilitiesService abilities;
        
        public ProjectsController()
            : this(new RoleServiceClient(), new ProjectsServiceClient(), new ProfileServiceClient(), new AbilitiesServiceClient())
        {
    
        }

        public ProjectsController(IRolesService roles, IProjectsService projects, IProfileService profile, IAbilitiesService abilities)
            : base(profile, projects)
        {
            this.roles = roles;
            this.abilities = abilities;
        }
        
        public void List()
        {
            ProjectListViewData data = new ProjectListViewData();

            Collection<Project> projectList = new Collection<Project> (this.Projects.GetProjects());

            DateTime todayFourMonthsBefore = DateTime.Today.AddMonths(-4);

            var currentProjects = projectList.Where( p => String.Compare(p.StartsOn.ToString("yyyyMM", CultureInfo.InvariantCulture), 
                    todayFourMonthsBefore.ToString("yyyyMM", CultureInfo.InvariantCulture), 
                    StringComparison.Ordinal) >= 0);

            data.Projects.Clear();
            foreach (Project p in currentProjects)
            {
                data.Projects.Add(p);
            }
                    
            data.Title = "Projects Running";
            data.IsCurrentList = true;
            data.FilterDate = todayFourMonthsBefore;

            RenderView("List", data);
        }

        public void ListHistoric()
        {
            ProjectListViewData data = new ProjectListViewData();

            Collection<Project> projectList = new Collection<Project>(this.Projects.GetProjects());

            DateTime todayFourMonthsBefore = DateTime.Today.AddMonths(-4);

            var currentProjects = projectList.Where(p => String.Compare(p.StartsOn.ToString("yyyyMM", CultureInfo.InvariantCulture),
                   todayFourMonthsBefore.ToString("yyyyMM", CultureInfo.InvariantCulture),
                   StringComparison.Ordinal) < 0);

            data.Projects.Clear();
            foreach (Project p in currentProjects)
            {
                data.Projects.Add(p);
            }
            data.Title = "Projects Running (History)";
            data.IsCurrentList = false;
            data.FilterDate = todayFourMonthsBefore;

            RenderView("List", data);
        }

        public void Home(string projectId)
        {
            ProjectsHomeViewData data = new ProjectsHomeViewData()
            {
                ProjectName = Projects.GetProjectName(projectId),
                ProjectId = projectId,
                ProjectSpecificMetrics = this.Projects.GetUriProjectSpecificMetrics(projectId),
                ViewTitle = "Home"
            };
            RenderView("Home", data);
        }

        public void New()
        {
            Project project = new Project
            {
                Id = Guid.Empty,
                Name = "new-project",
                Group = "project-new-project",
                RepositoryUri = string.Format(CultureInfo.InvariantCulture,"{0}/{1}", ConfigurationManager.AppSettings["defaultRootProjectRepository"], "new-project"),
                StartsOn = DateTime.Now,
                EndsOn = DateTime.Now, 
                ProjectSpecificMetricsUri = "http://"
            };

            ProjectsWriteViewData data = new ProjectsWriteViewData { Project = project };
            RenderView("Write", data);
        }

        public void Edit(string projectId)
        {
            Project project = Projects.GetProject(projectId);

            ProjectsWriteViewData data = new ProjectsWriteViewData { Project = project };
            RenderView("Write", data);
        }

        public void Save(string id, string name, string repositoryPath, string projectSpecificMetricsPath, string group, DateTime startsOn, DateTime endsOn)
        {
            Project project = new Project
            {
                Name = name,
                Group = group,
                RepositoryUri = repositoryPath,
                StartsOn = startsOn,
                EndsOn = endsOn,       
                ProjectSpecificMetricsUri = projectSpecificMetricsPath
            };

            Guid projectId = new Guid(id);
            if (projectId == Guid.Empty)
            {
                project.Id = Guid.NewGuid();
                Projects.Add(project);
            }
            else
            {
                project.Id = projectId;
                Projects.Update(project);
            }

            RedirectToAction(new { Action = "List"});
        }

        public void Abilities(string projectId, string roleId)
        {
            RoleAbilitiesViewData data = new RoleAbilitiesViewData(this.roles.GetAbilities(projectId, roleId));
            data.Role = this.roles.GetProjectRole(roleId);
            RenderView("RoleAbilities", data);
        }

        public void ReadRoles(string projectId)
        {
            ProjectRolesViewData data = new ProjectRolesViewData(this.roles.GetProjectRoles(projectId), new Collection<Ability> (abilities.GetAbilities()));
            data.ProjectId = projectId;
            data.ProjectName = this.Projects.GetProjectName(projectId);
            RenderView("Roles", data);            
        }

        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public void Team(string projectId)
        {
            TeamListViewData data = new TeamListViewData() 
            { 
                ExternalPersonsMails = "",
                InternalPersonsMails = "",
                ProjectId = projectId,
                ProjectName = Projects.GetProjectName(projectId),
                ViewTitle = "Team"
            };

            PersonAssignation[] pPersons = this.Projects.GetPersonsInProject(projectId);

            if (pPersons != null)
            {
                foreach (PersonAssignation person in pPersons)
                {
                    if (person.IsInternal)
                    {
                        data.InternalPersons.Add(person);
                        data.InternalPersonsMails += string.Concat(person.Person.Mail, ";");
                    }
                    else
                    {
                        data.ExternalPersons.Add(person);
                        data.ExternalPersonsMails += string.Concat(person.Person.Mail, ";");
                    }
                }
            }
            
            RenderView("Team", data);
        }

        [SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public void MakeTeam(string projectId)
        {
            PeopleTeamViewData data;

            PersonAssignation[] p = this.Projects.GetPersonsInProject(projectId);
            if (p != null)
            {
                data = new PeopleTeamViewData(Profile.GetPeople(), roles.GetProjectRoles(projectId), new Collection<PersonAssignation>(p));
            }
            else
            {
                data = new PeopleTeamViewData(Profile.GetPeople(), roles.GetProjectRoles(projectId), new Collection<PersonAssignation>());
            }

            data.ProjectId = projectId;
            data.ProjectName = this.Projects.GetProjectName(projectId);

            RenderView("MakeTeam", data);
        }

        public void AddPerson(string projectId, string personId, int inOut)
        {
            TeamMember member;
            string[] requestValues = Request.Form.GetValues("roleIds");

            if (requestValues != null)
            {
                member = new TeamMember(new Collection<string>(requestValues));
            }
            else
            {
                member = new TeamMember();
            }

            member.PersonId = personId;
            member.IsInternal = (inOut == 0);

            this.Projects.AddPersonToProject(projectId, member);

            RedirectToAction(new { Action = "MakeTeam", projectId = projectId });
        }

        public void RemovePerson(string projectId, string personId)
        {
            this.Projects.RemovePersonFromProject(projectId, personId);

            RedirectToAction(new { Action = "MakeTeam", projectId = projectId });
        }

        public void AddRole(string projectId, string role)
        {
            if (!String.IsNullOrEmpty(role))
                roles.AddRoleToProject(projectId, role, Request.Form.GetValues("abilities"));

            RedirectToAction(new { Action = "ReadRoles", projectId = projectId });
        }

        public void CChecker(string projectId)
        {
            ProjectCheckerViewData data = new ProjectCheckerViewData()
            {
                ProjectName = this.Projects.GetProjectName(projectId),
                ProjectId = projectId,
                ViewTitle = "Compliance Checker"
            };
           CheckStatus[] checkList = this.Projects.CheckCompliance(projectId);

           if (checkList != null)
           {
               foreach(CheckStatus checkStatus in checkList)
               {
                   data.Check.Add(checkStatus);
               }
           }

            RenderView("ComplianceChecker",data);
        }
    }
}
